#!/usr/bin/env python3
# vim: tabstop=4 shiftwidth=4 expandtab

from enum import Enum

class LineType(Enum):
    H1 = 1
    H2 = 2
    H3 = 3
    BLOCKQUOTE = 4
    PREFORM = 5
    LISTITEM = 6
    LINK = 7
    PLAIN = 8

class GemtextParser():

    def __init__(self) -> "GemtextParser":
        self.preformMode = False

    def parseText(self, text: str = None) -> "Array":
        lines = []
        if text:
            for line in text.splitlines():
                parsed = self.parseLine(line)
                if parsed:
                    lines.append(parsed)
        return lines

    def parseLine(self, line: str = None) -> "GemtextLine":
        if line == None:
            return None

        if line.startswith("```"):
            self.preformMode = not self.preformMode
            return None
        if self.preformMode:
            return GemtextLine(LineType.PREFORM, line)

        if line.startswith("###"):
            return GemtextLine(LineType.H3, line)
        if line.startswith("##"):
            return GemtextLine(LineType.H2, line)
        if line.startswith("#"):
            return GemtextLine(LineType.H1, line)
        if line.startswith("=>"):
            return GemtextLine(LineType.LINK, line)
        if line.startswith("* "):
            return GemtextLine(LineType.LISTITEM, line) 
        if line.startswith(">"):
            return GemtextLine(LineType.BLOCKQUOTE, line)
        return GemtextLine(LineType.PLAIN, line)

class GemtextLine():

    lineprefixes = {
        LineType.H1: "#",
        LineType.H2: "##",
        LineType.H3: "###",
        LineType.BLOCKQUOTE: ">",
        LineType.PREFORM: "",
        LineType.LISTITEM: "* ",
        LineType.LINK: "=>",
        LineType.PLAIN: ""
    }

    def __init__(self, linetype: LineType, line: str) -> "GemtextLine":
        self.linetype = linetype
        self.line = line

    def linkURL(self) -> "String":
        if (self.linetype == LineType.LINK):
           return self.line.removeprefix("=>").split()[0]
        return None

    def text(self) -> "String":
        line = self.line.removeprefix(self.lineprefixes[self.linetype])
        if self.linetype == LineType.LINK:
            fields = line.split(maxsplit=1)
            if len(fields) > 1:
                return fields[1]
            return ""
        if self.linetype in [LineType.PLAIN, LineType.PREFORM, LineType.LISTITEM]:
            return line
        return line.lstrip()

    def line(self) -> "String":
        return self.line

